[IA64] memmap: save/restore: support save/restore with domain memmap
authorAlex Williamson <alex.williamson@hp.com>
Thu, 24 May 2007 21:54:52 +0000 (15:54 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 24 May 2007 21:54:52 +0000 (15:54 -0600)
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
tools/libxc/ia64/xc_ia64_linux_restore.c
tools/libxc/ia64/xc_ia64_linux_save.c
xen/arch/ia64/xen/dom0_ops.c
xen/arch/ia64/xen/dom_fw_utils.c

index 5678a09f922f3374ea445c57cb32c9d2d4c57a90..509533904cc142c07be5fb6c71416e2a024cde47 100644 (file)
@@ -140,9 +140,7 @@ xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
     /* Build firmware (will be overwritten).  */
     domctl.domain = (domid_t)dom;
     domctl.u.arch_setup.flags &= ~XEN_DOMAINSETUP_query;
-    domctl.u.arch_setup.bp = ((p2m_size - 3) << PAGE_SHIFT)
-                           + sizeof (start_info_t);
-    domctl.u.arch_setup.maxmem = (p2m_size - 3) << PAGE_SHIFT;
+    domctl.u.arch_setup.bp = 0; /* indicate domain restore */
     
     domctl.cmd = XEN_DOMCTL_arch_setup;
     if (xc_domctl(xc_handle, &domctl))
@@ -330,3 +328,13 @@ xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
 
     return rc;
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index ceb91795c42b91b9f6f2726e479b14fcf0c3b2cf..f43f5b86ac1a4450123c86c0f27ffa504a89d0b5 100644 (file)
@@ -22,8 +22,8 @@
 ** XXX SMH: should consider if want to be able to override MAX_MBIT_RATE too.
 **
 */
-#define DEF_MAX_ITERS    (4 - 1)       /* limit us to 4 times round loop  */
-#define DEF_MAX_FACTOR   3             /* never send more than 3x nr_pfns */
+#define DEF_MAX_ITERS    (4 - 1)        /* limit us to 4 times round loop  */
+#define DEF_MAX_FACTOR   3              /* never send more than 3x nr_pfns */
 
 /*
 ** During (live) save/migrate, we maintain a number of bitmaps to track
 
 #define BITMAP_SHIFT(_nr) ((_nr) % BITS_PER_LONG)
 
-static inline int test_bit (int nr, volatile void * addr)
+static inline int test_bit(int nr, volatile void * addr)
 {
     return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;
 }
 
-static inline void clear_bit (int nr, volatile void * addr)
+static inline void clear_bit(int nr, volatile void * addr)
 {
     BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr));
 }
 
-static inline void set_bit ( int nr, volatile void * addr)
+static inline void set_bit(int nr, volatile void * addr)
 {
     BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr));
 }
 
-/* total number of pages used by the current guest */
-static unsigned long max_pfn;
-
 static int xc_ia64_shadow_control(int xc_handle,
                                   uint32_t domid,
                                   unsigned int sop,
@@ -67,7 +64,7 @@ static int xc_ia64_shadow_control(int xc_handle,
         unsigned char *bmap = (unsigned char *)dirty_bitmap;
         unsigned long bmap_bytes =
             ((pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG - 1)) / 8;
-        unsigned int bmap_pages = (bmap_bytes + PAGE_SIZE - 1) / PAGE_SIZE; 
+        unsigned int bmap_pages = (bmap_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
 
         /* Touch the page so that it is in the TC.
            FIXME: use a more reliable method.  */
@@ -168,6 +165,9 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
     /* Number of pages sent (live only).  */
     unsigned int total_sent;
 
+    /* total number of pages used by the current guest */
+    unsigned long p2m_size;
+
     /* Size of the shadow bitmap (live only).  */
     unsigned int bitmap_size = 0;
 
@@ -182,7 +182,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
     char *mem;
 
     if (debug)
-        fprintf (stderr, "xc_linux_save (ia64): started dom=%d\n", dom);
+        fprintf(stderr, "xc_linux_save (ia64): started dom=%d\n", dom);
 
     /* If no explicit control parameters given, use defaults */
     if (!max_iters)
@@ -216,17 +216,17 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         goto out;
     }
 
-    max_pfn = info.max_memkb >> (PAGE_SHIFT - 10);
+    p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom);
 
-    page_array = malloc(max_pfn * sizeof(unsigned long));
+    page_array = malloc(p2m_size * sizeof(unsigned long));
     if (page_array == NULL) {
         ERROR("Could not allocate memory");
         goto out;
     }
 
     /* This is expected by xm restore.  */
-    if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
-        ERROR("write: max_pfn");
+    if (!write_exact(io_fd, &p2m_size, sizeof(unsigned long))) {
+        ERROR("write: p2m_size");
         goto out;
     }
 
@@ -269,7 +269,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
         last_iter = 0;
 
-        bitmap_size = ((max_pfn + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
+        bitmap_size = ((p2m_size + BITS_PER_LONG-1) & ~(BITS_PER_LONG-1)) / 8;
         to_send = malloc(bitmap_size);
         to_skip = malloc(bitmap_size);
 
@@ -289,7 +289,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             ERROR("Unable to lock_pages to_skip");
             goto out;
         }
-        
+
     } else {
 
         /* This is a non-live suspend. Issue the call back to get the
@@ -304,7 +304,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
     }
 
-    sent_last_iter = max_pfn;
+    sent_last_iter = p2m_size;
     total_sent = 0;
 
     for (iter = 1; ; iter++) {
@@ -316,7 +316,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
         /* Get the pfn list, as it may change.  */
         if (xc_ia64_get_pfn_list(xc_handle, dom, page_array,
-                                 0, max_pfn) != max_pfn) {
+                                 0, p2m_size) != p2m_size) {
             ERROR("Could not get the page frame list");
             goto out;
         }
@@ -327,14 +327,14 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         if (!last_iter) {
             if (xc_ia64_shadow_control(xc_handle, dom,
                                        XEN_DOMCTL_SHADOW_OP_PEEK,
-                                       to_skip, max_pfn, NULL) != max_pfn) {
+                                       to_skip, p2m_size, NULL) != p2m_size) {
                 ERROR("Error peeking shadow bitmap");
                 goto out;
             }
         }
 
         /* Start writing out the saved-domain record. */
-        for (N = 0; N < max_pfn; N++) {
+        for (N = 0; N < p2m_size; N++) {
             if (page_array[N] == INVALID_MFN)
                 continue;
             if (!last_iter) {
@@ -346,7 +346,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
             if (debug)
                 fprintf(stderr, "xc_linux_save: page %lx (%lu/%lu)\n",
-                        page_array[N], N, max_pfn);
+                        page_array[N], N, p2m_size);
 
             mem = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
                                        PROT_READ|PROT_WRITE, N);
@@ -360,7 +360,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             }
 
             if (!write_exact(io_fd, &N, sizeof(N))) {
-                ERROR("write: max_pfn");
+                ERROR("write: p2m_size");
                 munmap(mem, PAGE_SIZE);
                 goto out;
             }
@@ -384,7 +384,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         if (live) {
             if ( /* ((sent_this_iter > sent_last_iter) && RATE_IS_MAX()) || */
                 (iter >= max_iters) || (sent_this_iter+skip_this_iter < 50) ||
-                (total_sent > max_pfn*max_factor)) {
+                (total_sent > p2m_size*max_factor)) {
                 DPRINTF("Start last iteration\n");
                 last_iter = 1;
 
@@ -397,7 +397,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             /* Pages to be sent are pages which were dirty.  */
             if (xc_ia64_shadow_control(xc_handle, dom,
                                        XEN_DOMCTL_SHADOW_OP_CLEAN,
-                                       to_send, max_pfn, NULL ) != max_pfn) {
+                                       to_send, p2m_size, NULL ) != p2m_size) {
                 ERROR("Error flushing shadow PT");
                 goto out;
             }
@@ -409,7 +409,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
 
     }
 
-    fprintf (stderr, "All memory is saved\n");
+    fprintf(stderr, "All memory is saved\n");
 
     /* terminate */
     {
@@ -425,7 +425,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         unsigned int i,j;
         unsigned long pfntab[1024];
 
-        for (i = 0, j = 0; i < max_pfn; i++) {
+        for (i = 0, j = 0; i < p2m_size; i++) {
             if (page_array[i] == INVALID_MFN)
                 j++;
         }
@@ -435,13 +435,13 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
             goto out;
         }
 
-        for (i = 0, j = 0; i < max_pfn; ) {
+        for (i = 0, j = 0; i < p2m_size; ) {
 
             if (page_array[i] == INVALID_MFN)
                 pfntab[j++] = i;
 
             i++;
-            if (j == 1024 || i == max_pfn) {
+            if (j == 1024 || i == p2m_size) {
                 if (!write_exact(io_fd, &pfntab, sizeof(unsigned long)*j)) {
                     ERROR("Error when writing to state file (6b)");
                     goto out;
@@ -475,7 +475,7 @@ xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
         munmap(mem, PAGE_SIZE);
         goto out;
     }
-    munmap(mem, PAGE_SIZE);    
+    munmap(mem, PAGE_SIZE);
 
     if (!write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
         ERROR("Error when writing to state file (1)");
index e0df61a3ad731899233d9e10dac4f004643468fc..1fc29b54631491157c4b2ab870ff445cdea44120 100644 (file)
@@ -89,7 +89,7 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
                 ds->flags |= XEN_DOMAINSETUP_hvm_guest;
             /* Set params.  */
             ds->bp = 0;                /* unknown.  */
-            ds->maxmem = 0; /* unknown.  */
+            ds->maxmem = d->arch.convmem_end;
             ds->xsi_va = d->arch.shared_info_va;
             ds->hypercall_imm = d->arch.breakimm;
             /* Copy back.  */
index d0d8b5249ea65cd43bc22e8e866da7d1dca473f3..51f915841328f1adf4f47f35fb3c25839209a28f 100644 (file)
@@ -139,6 +139,14 @@ assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
         assign_new_domain0_page(d, mpaddr);
 }
 
+static void
+dom_fw_setup_for_domain_restore(domain_t *d, unsigned long maxmem)
+{
+    assign_new_domain_page(d, FW_HYPERCALL_BASE_PADDR);
+    dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
+    d->arch.convmem_end = maxmem;
+}
+
 int
 dom_fw_setup(domain_t *d, unsigned long bp_mpa, unsigned long maxmem)
 {
@@ -149,6 +157,12 @@ dom_fw_setup(domain_t *d, unsigned long bp_mpa, unsigned long maxmem)
     BUILD_BUG_ON(sizeof(struct fw_tables) >
                  (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
 
+    if (bp_mpa == 0) {
+        /* bp_mpa == 0 means this is domain restore case. */
+        dom_fw_setup_for_domain_restore(d, maxmem);
+        return 0;
+    }
+
     /* Create page for boot_param.  */
     assign_new_domain_page_if_dom0(d, bp_mpa);
     bp = domain_mpa_to_imva(d, bp_mpa);